<?php

namespace App\Containers\AppSection\Moderation\UI\API\Requests;

use App\Containers\AppSection\Moderation\Tasks\FindModerationByIdTask;
use App\Ship\Parents\Requests\Request;
use App\Ship\Rules\ProhibitedRule;
use Illuminate\Validation\Rule;

class ModeratorCheckModerationRequest extends Request
{

    /**
     * Define which Roles and/or Permissions has access to this request.
     */
    protected array $access = [
        'permissions' => '',
        'roles' => 'moderator|admin',
    ];

    /**
     * Id's that needs decoding before applying the validation rules.
     */
    protected array $decode = [
        // 'id',
    ];

    /**
     * Defining the URL parameters (e.g, `/user/{id}`) allows applying
     * validation rules on them and allows accessing them like request data.
     */
    protected array $urlParameters = [
        // 'id',
    ];

    /**
     * Get the validation rules that apply to the request.
     */
    public function rules(): array
    {
        $moderation = app(FindModerationByIdTask::class)->run($this->id);
        $isEntity = $moderation->project->profile->hasLegalForm('entity');

        return [
            'type' => ['required', Rule::in(['projects_collecting', 'projects_returned', 'projects_rejected'])],

            'remarks' => ['array'],
            'remarks.*.type_key' => ['nullable', Rule::exists('types', 'key')->where(function ($query) {
                return $query->where('table', 'moderation_remarks');
            })],
            'remarks.*.message' => ['required', 'string'],

            'condition' => [],
            'condition.percent' => ['required', 'numeric'],
            'condition.loan' => ['required', 'numeric'],
            'condition.deffer_period' => $this->getInputByKey('condition.loan', 1) > 1 ? [
                Rule::requiredIf($moderation->project->condition->hasRepayment('deferred_annuity')),
                $this->getInputByKey('condition.loan', 1) > 35 ? 'max:35' : 'max:' . ($this->getInputByKey('condition.loan', 1) - 1),
                'min:1',
            ] : [new ProhibitedRule],
            'condition.penalty_per_day' => [
                $moderation->project->condition->hasRepayment('principal_and_fixed_interest') ? 'required' : 'nullable',
                'numeric', 'min:0', 'max:3'
            ],
            'condition.charge_penalty_first_day' => ['required', 'boolean'],
            'condition.percents_calculation' => [
                $moderation->project->condition->hasRepayment('principal_and_fixed_interest') &&
                $moderation->project->condition->hasRepayment('principal_and_annual_interest') ? 'required' : 'nullable',
                'numeric',
                'max:200',
                'min:5'
            ],
            'condition.output_key' => ['required', Rule::exists('types', 'key')->where(function ($query) {
                return $query->where('table', 'project_condition_outputs');
            })],

            'rate' => [],
            'rate.support' => ['required', 'numeric', 'min:1'],
            'rate.tariff' => ['required', 'numeric', 'min:1', 'max:100'],

            'analytic' => [],
            'analytic.credit_history' => ['required', 'string', 'max:200'],
            'analytic.suspension' => ['required', 'string', 'max:200'],
            'analytic.balance' => ['required', 'numeric'],
            'analytic.revenue' => ['required', 'numeric'],
            'analytic.net_profit' => ['required', 'numeric'],
            'analytic.nds' => ['required', 'numeric'],
            'analytic.contributions' => ['required', 'numeric'],
            'analytic.total_paid' => ['required', 'numeric'],
            'analytic.debt' => ['required', 'numeric'],

            'analytic.entries_egrul' => ['array', 'max:15'],
            'analytic.entries_egrul.*.date' => ['required', 'date_format:d.m.Y'],
            'analytic.entries_egrul.*.event' => ['required', 'string', 'max:700'],

            'analytic.arbitration_cases' => [],
            'analytic.arbitration_cases.plaintiff' => [],
            'analytic.arbitration_cases.plaintiff.year' => [],
            'analytic.arbitration_cases.plaintiff.year.money' => ['required', 'numeric'],
            'analytic.arbitration_cases.plaintiff.year.time' => ['required', 'numeric'],
            'analytic.arbitration_cases.plaintiff.all' => [],
            'analytic.arbitration_cases.plaintiff.all.money' => ['required', 'numeric'],
            'analytic.arbitration_cases.plaintiff.all.time' => ['required', 'numeric'],
            'analytic.arbitration_cases.respondent' => [],
            'analytic.arbitration_cases.respondent.year' => [],
            'analytic.arbitration_cases.respondent.year.money' => ['required', 'numeric'],
            'analytic.arbitration_cases.respondent.year.time' => ['required', 'numeric'],
            'analytic.arbitration_cases.respondent.all' => [],
            'analytic.arbitration_cases.respondent.all.money' => ['required', 'numeric'],
            'analytic.arbitration_cases.respondent.all.time' => ['required', 'numeric'],

            'analytic.execution_proceedings' => ['required', 'string', 'max:200'],
            'analytic.availability_lists' => ['required', 'string', 'max:200'],

            'analytic.government_purchases.participant' => [],
            'analytic.government_purchases.participant.sum' => ['required', 'numeric'],
            'analytic.government_purchases.participant.number' => ['required', 'numeric'],
            'analytic.government_purchases.contracts' => [],
            'analytic.government_purchases.contracts.sum' => ['required', 'numeric'],
            'analytic.government_purchases.contracts.number' => ['required', 'numeric'],

            'government' => [$isEntity ? 'required' : 'nullable'],
            'government.type_key' => [$isEntity ? 'required' : 'nullable', Rule::exists('types', 'key')->where(function ($query) {
                return $query->where('table', 'project_governments');
            })],
            'government.participants' => [$isEntity ? 'required' : 'nullable', 'array', 'max:100'],
            'government.participants.*.name' => [$isEntity ? 'required' : 'nullable', 'string', 'max:100'],
            'government.participants.*.share' => [$isEntity ? 'required' : 'nullable', 'numeric', 'min:1', 'max:100'],
            'government.body_name' => [$isEntity ? 'required' : 'nullable', 'string', 'max:100'],
            'government.participants_name' => [$isEntity ? 'required' : 'nullable', 'string', 'max:1000'],
            'government.persons_information' => [$isEntity ? 'required' : 'nullable', 'array'],
            'government.persons_information.*.name' => [$isEntity ? 'required' : 'nullable', 'string', 'max:100'],
            'government.persons_information.*.share' => [$isEntity ? 'required' : 'nullable', 'numeric', 'min:1', 'max:100'],
            'government.persons_information.*.inn' => [$isEntity ? 'required' : 'nullable', 'digits:10'],
            'government.persons_information.*.ogrn' => [$isEntity ? 'required' : 'nullable', 'digits:13'],
            'government.persons_information.*.address' => [$isEntity ? 'required' : 'nullable', 'string', 'max:400'],

            'pledges' => [count($moderation->project->pledges) > 0 ? 'required' : 'nullable', 'array', 'size:' . count($moderation->project->pledges)],
            'pledges.*.id' => ['required', Rule::exists('pledges', 'id')->where(function ($query) use ($moderation) {
                return $query->where('project_id', $moderation->project->id);
            })],
            'pledges.*.collateral_value' => ['required', 'numeric'],
            'pledges.*.description' => ['required', 'string', 'max:100'],
        ];
    }

    public function hasModeratorStage(): bool
    {
        $moderation = app(FindModerationByIdTask::class)->run($this->id);

        return $moderation->hasStage('moderator');
    }

    public function active(): bool
    {
        $moderation = app(FindModerationByIdTask::class)->run($this->id);

        return $moderation->project->moderation->id === $moderation->id;
    }

    public function checking(): bool
    {
        $moderation = app(FindModerationByIdTask::class)->run($this->id);

        return $moderation->project->hasModerationStatus('projects_checking');
    }

    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return $this->check([
            'hasAccess',
            'hasModeratorStage',
            'active',
            'checking'
        ]);
    }
}
